{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "f11db778",
   "metadata": {},
   "source": [
    "\n",
    "这里以中文BERT为例，实现提及聚类："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "0c9861b9",
   "metadata": {},
   "outputs": [
    {
     "ename": "HFValidationError",
     "evalue": "Repo id must use alphanumeric chars or '-', '_', '.', '--' and '..' are forbidden, '-' and '.' cannot start or end the name, max length is 96: 'E:\\huggingface\\hub\\models--bert-base-chinese'.",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mHFValidationError\u001b[0m                         Traceback (most recent call last)",
      "File \u001b[1;32m~\\anaconda3\\Lib\\site-packages\\transformers\\utils\\hub.py:424\u001b[0m, in \u001b[0;36mcached_files\u001b[1;34m(path_or_repo_id, filenames, cache_dir, force_download, resume_download, proxies, token, revision, local_files_only, subfolder, repo_type, user_agent, _raise_exceptions_for_gated_repo, _raise_exceptions_for_missing_entries, _raise_exceptions_for_connection_errors, _commit_hash, **deprecated_kwargs)\u001b[0m\n\u001b[0;32m    422\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mlen\u001b[39m(full_filenames) \u001b[38;5;241m==\u001b[39m \u001b[38;5;241m1\u001b[39m:\n\u001b[0;32m    423\u001b[0m     \u001b[38;5;66;03m# This is slightly better for only 1 file\u001b[39;00m\n\u001b[1;32m--> 424\u001b[0m     hf_hub_download(\n\u001b[0;32m    425\u001b[0m         path_or_repo_id,\n\u001b[0;32m    426\u001b[0m         filenames[\u001b[38;5;241m0\u001b[39m],\n\u001b[0;32m    427\u001b[0m         subfolder\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mNone\u001b[39;00m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mlen\u001b[39m(subfolder) \u001b[38;5;241m==\u001b[39m \u001b[38;5;241m0\u001b[39m \u001b[38;5;28;01melse\u001b[39;00m subfolder,\n\u001b[0;32m    428\u001b[0m         repo_type\u001b[38;5;241m=\u001b[39mrepo_type,\n\u001b[0;32m    429\u001b[0m         revision\u001b[38;5;241m=\u001b[39mrevision,\n\u001b[0;32m    430\u001b[0m         cache_dir\u001b[38;5;241m=\u001b[39mcache_dir,\n\u001b[0;32m    431\u001b[0m         user_agent\u001b[38;5;241m=\u001b[39muser_agent,\n\u001b[0;32m    432\u001b[0m         force_download\u001b[38;5;241m=\u001b[39mforce_download,\n\u001b[0;32m    433\u001b[0m         proxies\u001b[38;5;241m=\u001b[39mproxies,\n\u001b[0;32m    434\u001b[0m         resume_download\u001b[38;5;241m=\u001b[39mresume_download,\n\u001b[0;32m    435\u001b[0m         token\u001b[38;5;241m=\u001b[39mtoken,\n\u001b[0;32m    436\u001b[0m         local_files_only\u001b[38;5;241m=\u001b[39mlocal_files_only,\n\u001b[0;32m    437\u001b[0m     )\n\u001b[0;32m    438\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n",
      "File \u001b[1;32m~\\anaconda3\\Lib\\site-packages\\huggingface_hub\\utils\\_validators.py:106\u001b[0m, in \u001b[0;36mvalidate_hf_hub_args.<locals>._inner_fn\u001b[1;34m(*args, **kwargs)\u001b[0m\n\u001b[0;32m    105\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m arg_name \u001b[38;5;129;01min\u001b[39;00m [\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mrepo_id\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mfrom_id\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mto_id\u001b[39m\u001b[38;5;124m\"\u001b[39m]:\n\u001b[1;32m--> 106\u001b[0m     validate_repo_id(arg_value)\n\u001b[0;32m    108\u001b[0m \u001b[38;5;28;01melif\u001b[39;00m arg_name \u001b[38;5;241m==\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mtoken\u001b[39m\u001b[38;5;124m\"\u001b[39m \u001b[38;5;129;01mand\u001b[39;00m arg_value \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n",
      "File \u001b[1;32m~\\anaconda3\\Lib\\site-packages\\huggingface_hub\\utils\\_validators.py:160\u001b[0m, in \u001b[0;36mvalidate_repo_id\u001b[1;34m(repo_id)\u001b[0m\n\u001b[0;32m    159\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m REPO_ID_REGEX\u001b[38;5;241m.\u001b[39mmatch(repo_id):\n\u001b[1;32m--> 160\u001b[0m     \u001b[38;5;28;01mraise\u001b[39;00m HFValidationError(\n\u001b[0;32m    161\u001b[0m         \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mRepo id must use alphanumeric chars or \u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124m-\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124m, \u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124m_\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124m, \u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124m.\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124m, \u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124m--\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124m and \u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124m..\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124m are\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[0;32m    162\u001b[0m         \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m forbidden, \u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124m-\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124m and \u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124m.\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124m cannot start or end the name, max length is 96:\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[0;32m    163\u001b[0m         \u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m \u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;132;01m{\u001b[39;00mrepo_id\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124m.\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[0;32m    164\u001b[0m     )\n\u001b[0;32m    166\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m--\u001b[39m\u001b[38;5;124m\"\u001b[39m \u001b[38;5;129;01min\u001b[39;00m repo_id \u001b[38;5;129;01mor\u001b[39;00m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m..\u001b[39m\u001b[38;5;124m\"\u001b[39m \u001b[38;5;129;01min\u001b[39;00m repo_id:\n",
      "\u001b[1;31mHFValidationError\u001b[0m: Repo id must use alphanumeric chars or '-', '_', '.', '--' and '..' are forbidden, '-' and '.' cannot start or end the name, max length is 96: 'E:\\huggingface\\hub\\models--bert-base-chinese'.",
      "\nDuring handling of the above exception, another exception occurred:\n",
      "\u001b[1;31mHFValidationError\u001b[0m                         Traceback (most recent call last)",
      "Cell \u001b[1;32mIn[1], line 3\u001b[0m\n\u001b[0;32m      1\u001b[0m \u001b[38;5;28;01mimport\u001b[39;00m \u001b[38;5;21;01mtorch\u001b[39;00m\n\u001b[0;32m      2\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01mtransformers\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m AutoTokenizer, AutoModel\n\u001b[1;32m----> 3\u001b[0m tokenizer \u001b[38;5;241m=\u001b[39m AutoTokenizer\u001b[38;5;241m.\u001b[39mfrom_pretrained(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mE:\u001b[39m\u001b[38;5;124m\\\u001b[39m\u001b[38;5;124mhuggingface\u001b[39m\u001b[38;5;124m\\\u001b[39m\u001b[38;5;124mhub\u001b[39m\u001b[38;5;124m\\\u001b[39m\u001b[38;5;124mmodels--bert-base-chinese\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[0;32m      4\u001b[0m model \u001b[38;5;241m=\u001b[39m AutoModel\u001b[38;5;241m.\u001b[39mfrom_pretrained(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mE:\u001b[39m\u001b[38;5;124m\\\u001b[39m\u001b[38;5;124mhuggingface\u001b[39m\u001b[38;5;124m\\\u001b[39m\u001b[38;5;124mhub\u001b[39m\u001b[38;5;124m\\\u001b[39m\u001b[38;5;124mmodels--bert-base-chinese\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[0;32m      6\u001b[0m \u001b[38;5;66;03m# 进行分词\u001b[39;00m\n",
      "File \u001b[1;32m~\\anaconda3\\Lib\\site-packages\\transformers\\models\\auto\\tokenization_auto.py:910\u001b[0m, in \u001b[0;36mAutoTokenizer.from_pretrained\u001b[1;34m(cls, pretrained_model_name_or_path, *inputs, **kwargs)\u001b[0m\n\u001b[0;32m    907\u001b[0m     \u001b[38;5;28;01mreturn\u001b[39;00m tokenizer_class\u001b[38;5;241m.\u001b[39mfrom_pretrained(pretrained_model_name_or_path, \u001b[38;5;241m*\u001b[39minputs, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs)\n\u001b[0;32m    909\u001b[0m \u001b[38;5;66;03m# Next, let's try to use the tokenizer_config file to get the tokenizer class.\u001b[39;00m\n\u001b[1;32m--> 910\u001b[0m tokenizer_config \u001b[38;5;241m=\u001b[39m get_tokenizer_config(pretrained_model_name_or_path, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs)\n\u001b[0;32m    911\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m_commit_hash\u001b[39m\u001b[38;5;124m\"\u001b[39m \u001b[38;5;129;01min\u001b[39;00m tokenizer_config:\n\u001b[0;32m    912\u001b[0m     kwargs[\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m_commit_hash\u001b[39m\u001b[38;5;124m\"\u001b[39m] \u001b[38;5;241m=\u001b[39m tokenizer_config[\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m_commit_hash\u001b[39m\u001b[38;5;124m\"\u001b[39m]\n",
      "File \u001b[1;32m~\\anaconda3\\Lib\\site-packages\\transformers\\models\\auto\\tokenization_auto.py:742\u001b[0m, in \u001b[0;36mget_tokenizer_config\u001b[1;34m(pretrained_model_name_or_path, cache_dir, force_download, resume_download, proxies, token, revision, local_files_only, subfolder, **kwargs)\u001b[0m\n\u001b[0;32m    739\u001b[0m     token \u001b[38;5;241m=\u001b[39m use_auth_token\n\u001b[0;32m    741\u001b[0m commit_hash \u001b[38;5;241m=\u001b[39m kwargs\u001b[38;5;241m.\u001b[39mget(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m_commit_hash\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;28;01mNone\u001b[39;00m)\n\u001b[1;32m--> 742\u001b[0m resolved_config_file \u001b[38;5;241m=\u001b[39m cached_file(\n\u001b[0;32m    743\u001b[0m     pretrained_model_name_or_path,\n\u001b[0;32m    744\u001b[0m     TOKENIZER_CONFIG_FILE,\n\u001b[0;32m    745\u001b[0m     cache_dir\u001b[38;5;241m=\u001b[39mcache_dir,\n\u001b[0;32m    746\u001b[0m     force_download\u001b[38;5;241m=\u001b[39mforce_download,\n\u001b[0;32m    747\u001b[0m     resume_download\u001b[38;5;241m=\u001b[39mresume_download,\n\u001b[0;32m    748\u001b[0m     proxies\u001b[38;5;241m=\u001b[39mproxies,\n\u001b[0;32m    749\u001b[0m     token\u001b[38;5;241m=\u001b[39mtoken,\n\u001b[0;32m    750\u001b[0m     revision\u001b[38;5;241m=\u001b[39mrevision,\n\u001b[0;32m    751\u001b[0m     local_files_only\u001b[38;5;241m=\u001b[39mlocal_files_only,\n\u001b[0;32m    752\u001b[0m     subfolder\u001b[38;5;241m=\u001b[39msubfolder,\n\u001b[0;32m    753\u001b[0m     _raise_exceptions_for_gated_repo\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mFalse\u001b[39;00m,\n\u001b[0;32m    754\u001b[0m     _raise_exceptions_for_missing_entries\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mFalse\u001b[39;00m,\n\u001b[0;32m    755\u001b[0m     _raise_exceptions_for_connection_errors\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mFalse\u001b[39;00m,\n\u001b[0;32m    756\u001b[0m     _commit_hash\u001b[38;5;241m=\u001b[39mcommit_hash,\n\u001b[0;32m    757\u001b[0m )\n\u001b[0;32m    758\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m resolved_config_file \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[0;32m    759\u001b[0m     logger\u001b[38;5;241m.\u001b[39minfo(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mCould not locate the tokenizer configuration file, will try to use the model config instead.\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n",
      "File \u001b[1;32m~\\anaconda3\\Lib\\site-packages\\transformers\\utils\\hub.py:266\u001b[0m, in \u001b[0;36mcached_file\u001b[1;34m(path_or_repo_id, filename, **kwargs)\u001b[0m\n\u001b[0;32m    208\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mcached_file\u001b[39m(\n\u001b[0;32m    209\u001b[0m     path_or_repo_id: Union[\u001b[38;5;28mstr\u001b[39m, os\u001b[38;5;241m.\u001b[39mPathLike],\n\u001b[0;32m    210\u001b[0m     filename: \u001b[38;5;28mstr\u001b[39m,\n\u001b[0;32m    211\u001b[0m     \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs,\n\u001b[0;32m    212\u001b[0m ) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m Optional[\u001b[38;5;28mstr\u001b[39m]:\n\u001b[0;32m    213\u001b[0m \u001b[38;5;250m    \u001b[39m\u001b[38;5;124;03m\"\"\"\u001b[39;00m\n\u001b[0;32m    214\u001b[0m \u001b[38;5;124;03m    Tries to locate a file in a local folder and repo, downloads and cache it if necessary.\u001b[39;00m\n\u001b[0;32m    215\u001b[0m \n\u001b[1;32m   (...)\u001b[0m\n\u001b[0;32m    264\u001b[0m \u001b[38;5;124;03m    ```\u001b[39;00m\n\u001b[0;32m    265\u001b[0m \u001b[38;5;124;03m    \"\"\"\u001b[39;00m\n\u001b[1;32m--> 266\u001b[0m     file \u001b[38;5;241m=\u001b[39m cached_files(path_or_repo_id\u001b[38;5;241m=\u001b[39mpath_or_repo_id, filenames\u001b[38;5;241m=\u001b[39m[filename], \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs)\n\u001b[0;32m    267\u001b[0m     file \u001b[38;5;241m=\u001b[39m file[\u001b[38;5;241m0\u001b[39m] \u001b[38;5;28;01mif\u001b[39;00m file \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m \u001b[38;5;28;01melse\u001b[39;00m file\n\u001b[0;32m    268\u001b[0m     \u001b[38;5;28;01mreturn\u001b[39;00m file\n",
      "File \u001b[1;32m~\\anaconda3\\Lib\\site-packages\\transformers\\utils\\hub.py:470\u001b[0m, in \u001b[0;36mcached_files\u001b[1;34m(path_or_repo_id, filenames, cache_dir, force_download, resume_download, proxies, token, revision, local_files_only, subfolder, repo_type, user_agent, _raise_exceptions_for_gated_repo, _raise_exceptions_for_missing_entries, _raise_exceptions_for_connection_errors, _commit_hash, **deprecated_kwargs)\u001b[0m\n\u001b[0;32m    463\u001b[0m     \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mEnvironmentError\u001b[39;00m(\n\u001b[0;32m    464\u001b[0m         \u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;132;01m{\u001b[39;00mrevision\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m is not a valid git identifier (branch name, tag name or commit id) that exists \u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[0;32m    465\u001b[0m         \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mfor this model name. Check the model page at \u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[0;32m    466\u001b[0m         \u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mhttps://huggingface.co/\u001b[39m\u001b[38;5;132;01m{\u001b[39;00mpath_or_repo_id\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124m for available revisions.\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[0;32m    467\u001b[0m     ) \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01me\u001b[39;00m\n\u001b[0;32m    469\u001b[0m \u001b[38;5;66;03m# Now we try to recover if we can find all files correctly in the cache\u001b[39;00m\n\u001b[1;32m--> 470\u001b[0m resolved_files \u001b[38;5;241m=\u001b[39m [\n\u001b[0;32m    471\u001b[0m     _get_cache_file_to_return(path_or_repo_id, filename, cache_dir, revision) \u001b[38;5;28;01mfor\u001b[39;00m filename \u001b[38;5;129;01min\u001b[39;00m full_filenames\n\u001b[0;32m    472\u001b[0m ]\n\u001b[0;32m    473\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mall\u001b[39m(file \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m \u001b[38;5;28;01mfor\u001b[39;00m file \u001b[38;5;129;01min\u001b[39;00m resolved_files):\n\u001b[0;32m    474\u001b[0m     \u001b[38;5;28;01mreturn\u001b[39;00m resolved_files\n",
      "File \u001b[1;32m~\\anaconda3\\Lib\\site-packages\\transformers\\utils\\hub.py:471\u001b[0m, in \u001b[0;36m<listcomp>\u001b[1;34m(.0)\u001b[0m\n\u001b[0;32m    463\u001b[0m     \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mEnvironmentError\u001b[39;00m(\n\u001b[0;32m    464\u001b[0m         \u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;132;01m{\u001b[39;00mrevision\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m is not a valid git identifier (branch name, tag name or commit id) that exists \u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[0;32m    465\u001b[0m         \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mfor this model name. Check the model page at \u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[0;32m    466\u001b[0m         \u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mhttps://huggingface.co/\u001b[39m\u001b[38;5;132;01m{\u001b[39;00mpath_or_repo_id\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124m for available revisions.\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[0;32m    467\u001b[0m     ) \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01me\u001b[39;00m\n\u001b[0;32m    469\u001b[0m \u001b[38;5;66;03m# Now we try to recover if we can find all files correctly in the cache\u001b[39;00m\n\u001b[0;32m    470\u001b[0m resolved_files \u001b[38;5;241m=\u001b[39m [\n\u001b[1;32m--> 471\u001b[0m     _get_cache_file_to_return(path_or_repo_id, filename, cache_dir, revision) \u001b[38;5;28;01mfor\u001b[39;00m filename \u001b[38;5;129;01min\u001b[39;00m full_filenames\n\u001b[0;32m    472\u001b[0m ]\n\u001b[0;32m    473\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mall\u001b[39m(file \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m \u001b[38;5;28;01mfor\u001b[39;00m file \u001b[38;5;129;01min\u001b[39;00m resolved_files):\n\u001b[0;32m    474\u001b[0m     \u001b[38;5;28;01mreturn\u001b[39;00m resolved_files\n",
      "File \u001b[1;32m~\\anaconda3\\Lib\\site-packages\\transformers\\utils\\hub.py:134\u001b[0m, in \u001b[0;36m_get_cache_file_to_return\u001b[1;34m(path_or_repo_id, full_filename, cache_dir, revision)\u001b[0m\n\u001b[0;32m    130\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21m_get_cache_file_to_return\u001b[39m(\n\u001b[0;32m    131\u001b[0m     path_or_repo_id: \u001b[38;5;28mstr\u001b[39m, full_filename: \u001b[38;5;28mstr\u001b[39m, cache_dir: Union[\u001b[38;5;28mstr\u001b[39m, Path, \u001b[38;5;28;01mNone\u001b[39;00m] \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m, revision: Optional[\u001b[38;5;28mstr\u001b[39m] \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m\n\u001b[0;32m    132\u001b[0m ):\n\u001b[0;32m    133\u001b[0m     \u001b[38;5;66;03m# We try to see if we have a cached version (not up to date):\u001b[39;00m\n\u001b[1;32m--> 134\u001b[0m     resolved_file \u001b[38;5;241m=\u001b[39m try_to_load_from_cache(path_or_repo_id, full_filename, cache_dir\u001b[38;5;241m=\u001b[39mcache_dir, revision\u001b[38;5;241m=\u001b[39mrevision)\n\u001b[0;32m    135\u001b[0m     \u001b[38;5;28;01mif\u001b[39;00m resolved_file \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m \u001b[38;5;129;01mand\u001b[39;00m resolved_file \u001b[38;5;241m!=\u001b[39m _CACHED_NO_EXIST:\n\u001b[0;32m    136\u001b[0m         \u001b[38;5;28;01mreturn\u001b[39;00m resolved_file\n",
      "File \u001b[1;32m~\\anaconda3\\Lib\\site-packages\\huggingface_hub\\utils\\_validators.py:106\u001b[0m, in \u001b[0;36mvalidate_hf_hub_args.<locals>._inner_fn\u001b[1;34m(*args, **kwargs)\u001b[0m\n\u001b[0;32m    101\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m arg_name, arg_value \u001b[38;5;129;01min\u001b[39;00m chain(\n\u001b[0;32m    102\u001b[0m     \u001b[38;5;28mzip\u001b[39m(signature\u001b[38;5;241m.\u001b[39mparameters, args),  \u001b[38;5;66;03m# Args values\u001b[39;00m\n\u001b[0;32m    103\u001b[0m     kwargs\u001b[38;5;241m.\u001b[39mitems(),  \u001b[38;5;66;03m# Kwargs values\u001b[39;00m\n\u001b[0;32m    104\u001b[0m ):\n\u001b[0;32m    105\u001b[0m     \u001b[38;5;28;01mif\u001b[39;00m arg_name \u001b[38;5;129;01min\u001b[39;00m [\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mrepo_id\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mfrom_id\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mto_id\u001b[39m\u001b[38;5;124m\"\u001b[39m]:\n\u001b[1;32m--> 106\u001b[0m         validate_repo_id(arg_value)\n\u001b[0;32m    108\u001b[0m     \u001b[38;5;28;01melif\u001b[39;00m arg_name \u001b[38;5;241m==\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mtoken\u001b[39m\u001b[38;5;124m\"\u001b[39m \u001b[38;5;129;01mand\u001b[39;00m arg_value \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[0;32m    109\u001b[0m         has_token \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mTrue\u001b[39;00m\n",
      "File \u001b[1;32m~\\anaconda3\\Lib\\site-packages\\huggingface_hub\\utils\\_validators.py:160\u001b[0m, in \u001b[0;36mvalidate_repo_id\u001b[1;34m(repo_id)\u001b[0m\n\u001b[0;32m    154\u001b[0m     \u001b[38;5;28;01mraise\u001b[39;00m HFValidationError(\n\u001b[0;32m    155\u001b[0m         \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mRepo id must be in the form \u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mrepo_name\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124m or \u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mnamespace/repo_name\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124m:\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[0;32m    156\u001b[0m         \u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m \u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;132;01m{\u001b[39;00mrepo_id\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124m. Use `repo_type` argument if needed.\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[0;32m    157\u001b[0m     )\n\u001b[0;32m    159\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m REPO_ID_REGEX\u001b[38;5;241m.\u001b[39mmatch(repo_id):\n\u001b[1;32m--> 160\u001b[0m     \u001b[38;5;28;01mraise\u001b[39;00m HFValidationError(\n\u001b[0;32m    161\u001b[0m         \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mRepo id must use alphanumeric chars or \u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124m-\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124m, \u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124m_\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124m, \u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124m.\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124m, \u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124m--\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124m and \u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124m..\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124m are\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[0;32m    162\u001b[0m         \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m forbidden, \u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124m-\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124m and \u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124m.\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124m cannot start or end the name, max length is 96:\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[0;32m    163\u001b[0m         \u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m \u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;132;01m{\u001b[39;00mrepo_id\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124m.\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[0;32m    164\u001b[0m     )\n\u001b[0;32m    166\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m--\u001b[39m\u001b[38;5;124m\"\u001b[39m \u001b[38;5;129;01min\u001b[39;00m repo_id \u001b[38;5;129;01mor\u001b[39;00m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m..\u001b[39m\u001b[38;5;124m\"\u001b[39m \u001b[38;5;129;01min\u001b[39;00m repo_id:\n\u001b[0;32m    167\u001b[0m     \u001b[38;5;28;01mraise\u001b[39;00m HFValidationError(\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mCannot have -- or .. in repo_id: \u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;132;01m{\u001b[39;00mrepo_id\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124m.\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n",
      "\u001b[1;31mHFValidationError\u001b[0m: Repo id must use alphanumeric chars or '-', '_', '.', '--' and '..' are forbidden, '-' and '.' cannot start or end the name, max length is 96: 'E:\\huggingface\\hub\\models--bert-base-chinese'."
     ]
    }
   ],
   "source": [
    "import torch\n",
    "from transformers import AutoTokenizer, AutoModel\n",
    "tokenizer = AutoTokenizer.from_pretrained(\"E:\\huggingface\\hub\\models--bert-base-chinese\")\n",
    "model = AutoModel.from_pretrained(\"E:\\huggingface\\hub\\models--bert-base-chinese\")\n",
    "\n",
    "# 进行分词\n",
    "sentence=\"小明给小红一束花，她很高兴。\"\n",
    "subtokenized_sentence=tokenizer.tokenize(sentence)\n",
    "subtokenized_sentence = [tokenizer._cls_token] + \\\n",
    "    subtokenized_sentence + [tokenizer._sep_token]\n",
    "subtoken_ids_sentence = tokenizer.convert_tokens_to_ids(\\\n",
    "    subtokenized_sentence)\n",
    "print(subtokenized_sentence)\n",
    "print(subtoken_ids_sentence)\n",
    "\n",
    "# 计算对应的特征\n",
    "outputs = model(torch.Tensor(subtoken_ids_sentence).\\\n",
    "    unsqueeze(0).long())\n",
    "hidden_states = outputs[0]\n",
    "print(hidden_states.shape)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "49d7247c",
   "metadata": {},
   "source": [
    "假设已经通过提及检测模型找到了句子中的提及，这里用每个提及的第一个子词（在中文中也就是第一个字）作为词特征："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "60d1eedf",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "torch.Size([4, 768])\n"
     ]
    }
   ],
   "source": [
    "# 提及的跨度，假设(-1,0)表示[CLS]的跨度，用于表示空提及[NA]，\n",
    "# 在实际训练中也可以额外定义个空提及符号\n",
    "mention_spans = [(-1,0),(0,2),(3,5),(10,11)]\n",
    "word_features = torch.concat([hidden_states[0,x+1].unsqueeze(0)\\\n",
    "    for (x,y) in mention_spans],0)\n",
    "print(word_features.shape)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fd5d787f",
   "metadata": {},
   "source": [
    "首先，通过双仿射函数计算打分。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "ca991cb8",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "tensor([[[     -inf,      -inf,      -inf,      -inf],\n",
      "         [-494.1196,      -inf,      -inf,      -inf],\n",
      "         [-684.3828, -726.1643,      -inf,      -inf],\n",
      "         [-318.4721, -654.2186, -698.3372,      -inf]]],\n",
      "       grad_fn=<AddBackward0>)\n",
      "tensor([[0, 0, 0]])\n"
     ]
    }
   ],
   "source": [
    "import sys\n",
    "sys.path.append('./code')\n",
    "from my_utils import Biaffine\n",
    "biaffine = Biaffine(word_features.shape[1])\n",
    "\n",
    "# 对word_features进行打分\n",
    "scores = biaffine(word_features.unsqueeze(0),\\\n",
    "    word_features.unsqueeze(0))\n",
    "# 由于只关注当前提及之前的提及是否与其进行共指，\n",
    "# 因此将它转换为下三角函数，并且为上三角部分置为负无穷：\n",
    "scores = scores.tril(diagonal=-1)\n",
    "inf_mask = torch.zeros_like(scores)-torch.inf\n",
    "inf_mask = inf_mask.triu()\n",
    "scores += inf_mask\n",
    "print(scores)\n",
    "print(scores.argmax(-1)[:,1:])"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "de88f8d7",
   "metadata": {},
   "source": [
    "由于模型未经过训练，因此仅通过双仿射函数初始化获得结构显然是错误的。我们可以训练模型，计算损失函数计算方式如下："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "9f2abedd",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "tensor(111.9155, grad_fn=<NllLossBackward0>)\n"
     ]
    }
   ],
   "source": [
    "# 只计算除了[NA]以外的提及的损失\n",
    "target = torch.Tensor([0,0,1]).long()\n",
    "loss_func = torch.nn.NLLLoss()\n",
    "loss = loss_func(torch.nn.functional.log_softmax(scores[:,1:].\\\n",
    "    squeeze(0),-1),target)\n",
    "print(loss)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "880e61fb",
   "metadata": {},
   "source": [
    "接下来通过点积计算打分。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "f6a04704",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "tensor([[    -inf,     -inf,     -inf,     -inf],\n",
      "        [235.2012,     -inf,     -inf,     -inf],\n",
      "        [188.3145, 267.1165,     -inf,     -inf],\n",
      "        [221.3709, 101.3910, 292.7802,     -inf]], grad_fn=<AddBackward0>)\n",
      "tensor([0, 1, 2])\n"
     ]
    }
   ],
   "source": [
    "scores2 = torch.matmul(word_features,word_features.T)\n",
    "scores2 = scores2.tril(diagonal=-1)\n",
    "inf_mask = torch.zeros_like(scores2)-torch.inf\n",
    "inf_mask = inf_mask.triu()\n",
    "scores2 += inf_mask\n",
    "print(scores2)\n",
    "print(scores2.argmax(-1)[1:])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "842f4689-f832-4218-9910-3f693cefb278",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
